package com.eportal.service.impl;

import com.eportal.aop.LogAnnotation;
import com.eportal.base.BaseDAO;
import com.eportal.dao.SysoptEntityMapper;
import com.eportal.domain.Sysopt;
import com.eportal.domain.TAgent;
import com.eportal.domain.TCommunity;
import com.eportal.entity.SysoptEntity;
import com.eportal.exception.NotUniqueException;
import com.eportal.filter.AuthenticationFilter;
import com.eportal.service.BaseServiceImpl;
import com.eportal.service.SysOptService;
import com.eportal.service.SysmenuService;
import com.eportal.util.MD5;
import com.eportal.util.SmsHelper;
import com.eportal.util.ValidateUtil;
import com.eportal.util.WebUtil;
import com.eportal.vo.controller.background.sysopt.SysoptSelectListVO;
import com.framework.jqgrid.JqGridPager;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
 * SysOptServiceImpl
 * @author chencheng
 */

@Service("sysOptService")
public class SysOptServiceImpl extends BaseServiceImpl<SysoptEntity> implements SysOptService {
	 private Logger logger = LoggerFactory.getLogger(SysOptServiceImpl.class);
	 private Map<String, Object> result = new HashMap<String, Object>();

	 @Resource(name="dao")
	 private BaseDAO dao;
	 @Resource(name="sysmenuService")
	 private SysmenuService sysmenuService;

	@Resource
	private SysoptEntityMapper sysoptDao;



    @Override
    public Sysopt save(Sysopt user) throws Exception {
    	dao.save(user);
    	return user;
    }

    private void delete(Long id) {
    	Sysopt user = (Sysopt) dao.getById(Sysopt.class, id);
    	dao.delete(user);
    }

    @Override
    public void delete(List<Long> ids) {
        for (Long id : ids) {
            delete(id);
        }
    }

    @Override
    public Sysopt get(Long id) {
        return (Sysopt) dao.getById(Sysopt.class, id);
    }

    @Override
    public void update(Sysopt user) throws Exception {
    	try {
    		dao.update(user);
        } catch (Exception e) {
            logger.error("",e);
        }

    }

    @Override
    public List<Map<String, Object>> list(JqGridPager jqGridPager, String sql) {
//    	String sql = "select * from Sysopt";
    	List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> users = dao.query(sql, jqGridPager);
        if (users == null || users.size() <1) {
        	return result;
		}
        // 获取用户的角色
        for (Map<String, Object> user : users) {
            String rids = (String) user.get("ROLES");
            if(rids!=null){
            	//获取用户对应的角色名
            	 final List<Long> ids = new ArrayList<Long>();
                 for (String s : rids.split("\\|")) {
                     ids.add(Long.parseLong(s));
                 }
                 String sqlTemp = "select rName from Sysroles where sid in (:ids)";
                 List<String>  temp = dao.executeFind(sqlTemp, "ids", ids);
                 user.remove("ROLES");
                 for (String str : temp) {
                     if (user.containsKey("ROLES")) {
                         user.put("ROLES", user.get("ROLES") + " ," + str);
                     } else {
                         user.put("ROLES", str);
                     }
                 }
            }
            result.add(user);
        }
        return result;


    }

    @Override
    public List<Sysopt> find(Map<String, Object> param) {
        StringBuffer hql = new StringBuffer("from Sysopt");
        LinkedList<Object> values = null;
        if (!param.isEmpty()) {
            values = new LinkedList<Object>();
            hql.append(" where ");
            Set<Map.Entry<String, Object>> set = param.entrySet();
            int i = 1;

            for (Iterator<Map.Entry<String, Object>> iter = set.iterator(); iter.hasNext(); i++) {
                Map.Entry<String, Object> entry = iter.next();
                if (i != set.size()) {
                    hql.append(entry.getKey() + " = ? and ");
                } else {
                    hql.append(entry.getKey() + " = ?");
                }
                values.add(entry.getValue());
            }
        }
        List<Sysopt> list = dao.find(hql.toString(),values.toArray());
        return list;
    }

	@Override
	public List<Sysopt> getByUserName(String userName) {
		StringBuffer sb = new StringBuffer("from Sysopt where userName='");
		sb.append(userName);
		sb.append("'");
		return dao.query(sb.toString());
	}

	@Override
	public boolean ifUserRoleExist(String roleId) {
		StringBuffer sb = new StringBuffer("from Sysopt where roles='");
		sb.append(roleId);
		sb.append("'");
		List<Sysopt> list = dao.query(sb.toString());
		if(list != null && list.size()>0){
    		return true;
    	}else{
    		return false;
    	}
	}

	/**
     * 管理员登录方法
     */
    @LogAnnotation(operateDescribe="管理员登录")
    public Map<String, Object> loginMethod(Map<String, Object> param) {
        try{
             List<Sysopt> users = find(param);
             // 清空map数据
             param.clear();
             if (users != null && users.size() == 1) {
            	 Sysopt user = users.get(0);
            	 param = doLogin(user,param);

             }else {
                 param.put("code", 0);
                 param.put("msg", "用户名或密码错误");
             }
        }catch(Exception e){
        	logger.error("管理员登录异常:", e);
        	 param.put("code", 0);
             param.put("msg", "系统繁忙,请重试");
        }
        return param;
    }
    private Map<String, Object>  doLogin(Sysopt user, Map<String, Object> param) {
    	param.put("objectId", user.getSid());
   	 //如果状态为禁止状态，则不能登录
        if("0".equals(user.getStatus())){
       	 param.put("code", 0);
            param.put("msg", "用户被禁止");
            return param;
        }
        getSession().setAttribute("user", user);
		int userRole=0;
        if("-1".equals(user.getIsAdmin())){
			userRole=1; //Created by Saber on 2017/8/8 下午2:38
			getSession().setAttribute("userRole", 1);//平台超级管理员
        }
        if("0".equals(user.getIsAdmin())){
       	 if(user.getrLevel()==0){
			 userRole=2;//Created by Saber on 2017/8/8 下午2:38
       		 getSession().setAttribute("userRole", 2);//平台普通管理员
       	 }
        //区域主管
       	 if(user.getrLevel()==5){
			 userRole=21;//Created by Saber on 2017/8/8 下午2:38
       		 getSession().setAttribute("userRole", 21);
       	 }
       	//合作方普通管理员
       	 if(user.getrLevel()==1 || user.getrLevel()==3){ //物业公司 锁厂
			 userRole=4;//Created by Saber on 2017/8/8 下午2:38
       		 getSession().setAttribute("userRole", 4);
       	 }
       	//社区普通管理员
       	 if(user.getrLevel()==2 || user.getrLevel()==4){
			 userRole=6;//Created by Saber on 2017/8/8 下午2:38
       		 getSession().setAttribute("userRole", 6);
       	 }
        }

        if("1".equals(user.getIsAdmin())){
        	//合作方超级管理员
        	 if(user.getrLevel()==1 || user.getrLevel()==3){ //物业 锁厂
				 userRole=3;//Created by Saber on 2017/8/8 下午2:38
        		 getSession().setAttribute("userRole", 3);
        	 }
        	//社区超级管理员
        	 if(user.getrLevel()==2 || user.getrLevel()==4){
				 userRole=5;//Created by Saber on 2017/8/8 下午2:38
        		 getSession().setAttribute("userRole", 5);
        	 }
        }

		//主板厂商 todo  Created by Saber on 2017/7/25 下午4:04
		if(user.getrLevel()==6){
			userRole=7;//Created by Saber on 2017/8/8 下午2:38
			getSession().setAttribute("userRole",7);
		}

        if (user.getRoles() != null) {
            Map<String, Object> auths = sysmenuService.loadAuths(user,userRole);
            if(auths.size()<1){
           	 param.put("code", 0);
                param.put("msg", "角色被禁用或菜单列表为空");
                return param;
            }
            String default_access = (String) AuthenticationFilter.systemParam.get("default_access");
            auths.put("auths", auths.get("auths") + default_access);
            getSession().setAttribute("auths", auths);
        }
        WebUtil.setBackgroudUser(true);
        param.put("code", 1);
        param.put("msg", "登录成功");
        return param;

	}

	public HttpSession getSession() {
        return ServletActionContext.getRequest().getSession();
    }

	/**
     * 用户保存
     */
    @LogAnnotation(operateDescribe="用户保存")
    public Map<String, Object> addMethod(Sysopt sysopt) {
        String msg = ValidateUtil.validate(sysopt);
        if (msg == null || msg.trim().length() == 0) {
            try {
            	Sysopt  user= (Sysopt)getSession().getAttribute("user");
            	if (user.getAgtCode() != null) {
            		sysopt.setAgtCode(user.getAgtCode());
				}
            	if(user.getCommunityId() != null){
            		sysopt.setCommunityId(user.getCommunityId());
            	}
            	if(ifUserExist(sysopt)){
            		result.put("code", 0);
                    result.put("msg", "用户名已存在");
                    return result;
            	}
            	if (StringUtils.isBlank(sysopt.getPasswd())) {
            		result.put("code", 0);
                    result.put("msg", "用户登录密码必填");
                    return result;
				}
            	if (sysopt.getrLevel()!=null && sysopt.getrLevel() != 0) {
            		sysopt.setrLevel(sysopt.getrLevel());
				}else{
					sysopt.setrLevel(user.getrLevel());
				}
            	sysopt.setIsAdmin("0");
            	sysopt.setcName(Long.toString(user.getSid()));
            	sysopt.setcTime(new Timestamp(System.currentTimeMillis()));
            	sysopt.setPasswd(MD5.MD5Encode(sysopt.getPasswd()));
            	sysopt.setRoles(sysopt.getRoles().replace(", ","|").trim());
            	save(sysopt);
            	result.put("objectId", sysopt.getSid());
                result.put("code", 1);
                result.put("msg", "操作成功");
            } catch (Exception e) {
                logger.error("添加人员失败", e);
                result.put("code", 0);
                result.put("msg", "操作失败");
            }
        } else {
        	result.put("code", 0);
            result.put("msg", msg);
        }
        return result;
    }

	/**
     * 用户更新保存
     */
    @LogAnnotation(operateDescribe="用户更新")
    public Map<String, Object> updateMethod(Sysopt sysopt) {
        String msg = ValidateUtil.validate(sysopt);
        result.put("objectId", sysopt.getSid());
        if (msg == null || msg.trim().length() == 0) {
            try {
            	if (!ifHasRole(sysopt.getSid())) {
            		result.put("code", 0);
            		result.put("msg", "没有权限");
            		return result;
            	}
            	Sysopt entity = get(sysopt.getSid());
            	entity.setUname(sysopt.getUname());
            	if (sysopt.getrLevel() != 0) {
            		entity.setrLevel(sysopt.getrLevel());
				}
            	if(sysopt.getPasswd()!=null){
            		entity.setPasswd(MD5.MD5Encode(sysopt.getPasswd()));
            	}
            	entity.setTel(sysopt.getTel());
            	entity.setAddr(sysopt.getAddr());
            	entity.setStatus(sysopt.getStatus());
            	entity.setRoles(sysopt.getRoles().replace(", ","|").trim());
                update(entity);
                result.put("code", 1);
                result.put("msg", "操作成功");
            } catch (Exception e) {
                logger.error("修改人员失败", e);
                result.put("code", 0);
                result.put("msg", "操作失败");
            }
        } else {
        	result.put("code", 0);
            result.put("msg", msg);
        }
        return result;
    }

	/**
     * 超级管理员用户更新密码保存
     */
    public Map<String, Object> updateManagerMethod(Sysopt sysopt) {
        try {
        	result.put("objectId", sysopt.getSid());
        	if (!ifHasRole(sysopt.getSid())) {
        		result.put("code", 0);
        		result.put("msg", "没有权限");
        		return result;
        	}
        	Sysopt entity = get(sysopt.getSid());
        	if(StringUtils.isNotBlank(sysopt.getPasswd())){
        		entity.setPasswd(MD5.MD5Encode(sysopt.getPasswd()));
        	}
        	if (StringUtils.isNotBlank(sysopt.getStatus())) {
        		entity.setStatus(sysopt.getStatus());
			}
            update(entity);
            result.put("code", 1);
            result.put("msg", "操作成功");
        } catch (Exception e) {
            logger.error("修改人员失败", e);
            result.put("code", 0);
            result.put("msg", "操作失败");
        }
        return result;
    }

	 /**
     * 用户删除
     */
	@Override
    @LogAnnotation(operateDescribe="用户删除")
    public Map<String, Object> deleteMethod(String ids) {
        try {
        	result.put("objectId", ids);
            String[] sparams = ids.split(",");
            List<Long> params = new ArrayList<Long>();
            for (String s : sparams) {
            	if (!ifHasRole(Long.parseLong(s))) {
            		result.put("code", 0);
            		result.put("msg", "没有权限");
            		return result;
            	}
                params.add(Long.parseLong(s));
            }
            delete(params);
            result.put("code", 1);
            result.put("msg", "操作成功");
        } catch (Exception e) {
            logger.error("删除人员失败", e);
            result.put("code", 0);
            result.put("msg", "操作失败");
        }
        return result;
    }

	 /**
     * 用户名是否存在
     */
	public boolean ifUserExist(Sysopt sysopt){
    	List<Sysopt> list = getByUserName(sysopt.getUserName());
    	if(list != null && list.size()>0){
    		return true;
    	}else{
    		return false;
    	}
    }

	/**
     * 判断是否有对操作员的修改权限
     * @throws IOException
     */
    private boolean ifHasRole(Long sid) throws IOException {
    	Sysopt sysopt1 = get(sid);
    	Sysopt  user= (Sysopt)getSession().getAttribute("user");
    	int userRole =  (Integer) getSession().getAttribute("userRole");
    	if(userRole == 1){//平台超级管理员
    		return true;
    	}
    	//是否属于内部人员
    	if(sysopt1.getAgtCode().equals(user.getAgtCode()) && sysopt1.getCommunityId().equals(user.getCommunityId())){
    		return true;
    	}
    	if(userRole == 2){
    		//平台普通管理员可以修改合作方超级管理员的密码
    		if("1".equals(sysopt1.getIsAdmin()) && sysopt1.getrLevel()==1){
    			return true;
    		}
    	}
    	if(userRole == 3 || userRole == 4){
    		if("1".equals(sysopt1.getIsAdmin()) && sysopt1.getrLevel()==2){//判断是否是社区超级管理员
    			return true;
    		}
    	}
    	return false;
	}


	@Override
	public List<Sysopt> list(String hql) {
		return dao.query(hql);
	}

	/**
     * 合作方超级管理员创建保存
     */
	@Override
	public Map<String, Object> creatAgtManager(TAgent tagent, String agtCode) {
		  try {
          	Sysopt sysopt = new Sysopt();
          	sysopt.setUserName(tagent.getAdminUser());
          	sysopt.setPasswd(tagent.getComm());
          	if(ifUserExist(sysopt)){
          		result.put("code", 0);
                  result.put("msg", "登录账号已存在");
                  return result;
          	}
      		sysopt.setCommunityId("0");
			  //rlevel  0:平台级别  1:物业公司 忽略 2:小区级别 3:锁厂 4:锁厂客户 5:区域经理  6:主板厂商
      		if("1".equals(tagent.getType())){
      			sysopt.setrLevel(3);//锁厂
      		}else if("2".equals(tagent.getType())){  //主板厂商 todo Created by Saber on 2017/7/25 下午2:45
				sysopt.setrLevel(6);//主板厂商
			}else {
      			sysopt.setrLevel(1);//平台
      		}
          	sysopt.setAgtCode(agtCode);
          	sysopt.setIsAdmin("1");
          	sysopt.setcTime(new Timestamp(System.currentTimeMillis()));
          	sysopt.setPasswd(MD5.MD5Encode(sysopt.getPasswd()));
          	sysopt.setTel(tagent.getAgtTel());
          	sysopt.setAddr(tagent.getAddress());
          	sysopt.setUname(tagent.getAgtContact());
          	sysopt.setStatus("1");
          	if("2".equals(tagent.getAppType())){
          		sysopt.setRoles("2|6");//私人定制
          	}else{
          		sysopt.setRoles("2");//未审核通过的角色
          	}

          	sysopt = save(sysopt);
          	result.put("sid", sysopt.getSid());
          	result.put("code", 1);
              result.put("msg", "操作员保存成功");
          } catch (Exception e) {
              logger.error("添加合作方管理员失败", e);
              result.put("code", 0);
              result.put("msg", "操作员生成失败");
          }
          return result;
	}

	/**
     * 社区超级管理员创建保存
     */
	@Override
	public Map<String, Object> creatComuManager(TCommunity tCommunity, String communityId, String roleId, String typeAPP) {
		 try {
	          	Sysopt sysopt = new Sysopt();
	          	sysopt.setUserName(tCommunity.getAdminUser());
	          	sysopt.setPasswd(tCommunity.getComm());
	          	if("3".equals(roleId)){//普通社区
	          		if(ifUserExist(sysopt)){
		          		result.put("code", 0);
		                result.put("msg", "账号已存在");
		                return result;
		          	}
	          		sysopt.setrLevel(2);
	          	}else{//锁厂客户
	          		if("0".equals(typeAPP)){//app注册
	          			if(ifUserExist(sysopt)){
	          				for (int i = 1; i <= 58; i++) {
	          					sysopt.setUserName((char)(i+64)+tCommunity.getAdminUser());
	          					if(!ifUserExist(sysopt)){
	          						break;
	          					}
	          				}
	          			}
	          			String userId = (String) getSession().getAttribute("app_userid");
	          			sysopt.setAppUserid(userId);
					}else{
						if(ifUserExist(sysopt)){
			          		result.put("code", 0);
			                result.put("msg", "账号已存在");
			                return result;
			          	}
					}
	          		sysopt.setrLevel(4);
	          	}
	          	if(StringUtils.isNotBlank(sysopt.getPasswd())){
	          		sysopt.setPasswd(MD5.MD5Encode(sysopt.getPasswd()));
	          	}
	          	sysopt.setCommunityId(communityId);
	          	sysopt.setAgtCode(tCommunity.getAgtCode());
	          	sysopt.setIsAdmin("1");
	          	sysopt.setcTime(new Timestamp(System.currentTimeMillis()));
	        	sysopt.setTel(tCommunity.getDepartTel());
	          	sysopt.setAddr(tCommunity.getStreet());
	          	sysopt.setUname(tCommunity.getComContact());
	          	sysopt.setStatus("1");
	          	sysopt.setRoles(roleId);//角色
	          	Sysopt sys= save(sysopt);
	          	result.put("sid", sys.getSid());
	          	result.put("code", 1);
	            result.put("msg", "操作员保存成功");
	          } catch (Exception e) {
	              logger.error("添加社区管理员失败", e);
	              result.put("code", 0);
	              result.put("msg", "操作员生成失败");
	          }
	          return result;
	}

	@Override
	public void updateManager(String adminUser, String roleId) throws Exception {
		Sysopt sysopt = get(Long.parseLong(adminUser));
		sysopt.setRoles(roleId);
		update(sysopt);
	}

	@Override
	@LogAnnotation(operateDescribe="重置密码")
	public Map<String, Object> resetPasswordMethod(Sysopt sysopt) {
		try {
			List<Sysopt> list = getByUserName(sysopt.getUserName());
			Sysopt entity = list.get(0);
        	if(sysopt.getPasswd()!=null){
        		entity.setPasswd(MD5.MD5Encode(sysopt.getPasswd()));
        	}
            update(entity);
        	result.put("objectId", entity.getSid());
            result.put("code", 1);
            result.put("msg", "重置密码成功");
        } catch (Exception e) {
            logger.error("重置密码失败", e);
            result.put("code", 0);
            result.put("msg", "重置密码失败");
        }
		return result;
	}

	/**
     * 用户密码修改
     */
	@Override
	@LogAnnotation(operateDescribe="用户密码修改")
	public Map<String, Object> updatePasswordMethod(String sid, String oldPassword, String newPassword) {
        result.put("objectId", sid);
        try {
        	Sysopt entity = get(Long.parseLong(sid));
        	if (entity == null) {
        		 result.put("code", 0);
                 result.put("msg", "用户不存在");
                 return result;
			}
        	oldPassword = MD5.MD5Encode(oldPassword);
        	if(!oldPassword.equals(entity.getPasswd())){
        		result.put("code", 0);
                result.put("msg", "原密码不匹配，请重新输入");
                return result;
        	}
        	entity.setPasswd(MD5.MD5Encode(newPassword));
            update(entity);
            result.put("code", 1);
            result.put("msg", "操作成功，下次登录时生效");
        } catch (Exception e) {
            logger.error("修改人员失败", e);
            result.put("code", 0);
            result.put("msg", "操作失败");
        }
        return result;
	}

	@Override
	@LogAnnotation(operateDescribe="忘记密码发送验证码")
	public Map<String, Object> sendSMSVaildCodeMethod(String phone) {
		 try {
			 result.put("objectId", phone);
    		String code = SmsHelper.sendSMSVaildCode(phone);
			result.put("code", 1);
			result.put("msg", "发送成功");
		} catch (Exception e) {
			result.put("code", 0);
			result.put("msg", "发送失败");
			logger.error("忘记密码发送验证码异常:",e);
		}
		 return result;

	}

	@Override
	public Sysopt getByAppUserid(String appUserid) throws NotUniqueException {
		String hql="from Sysopt where appUserid= '"+appUserid+"'";
		return (Sysopt)dao.getUniqueFirst(hql);
	}

	@Override
	public Map<String, Object> loginBySysopt(Sysopt sysopt) {
		Map map = new HashMap();
		return doLogin(sysopt, map);
	}



//todo --------------------------------------------------------------------------------------


    /**
     * 操作人列表（下拉）
     *
     * @param type     类型 allComu:小区级、area:区域经理, 空:内部账号
     * @param user     当前用户
     * @param userRole 当前用户userRole
     * @return
     * @author Saber
     * @Date 2017/8/2 上午11:05
     */
    @Override
    public List<SysoptSelectListVO> selectList(String type, Sysopt user, int userRole) {

        String agtCode = null;
        String communityId = null;

        //内部账号
        if (StringUtils.isBlank(type)) {
            agtCode = user.getAgtCode();
            communityId = user.getCommunityId();
//            where.append("and agtCode ='");
//            where.append(user.getAgtCode());
//            where.append("' ");
//            where.append("and communityId ='");
//            where.append(user.getCommunityId());
//            where.append("' ");
        }else if("allComu".equals(type)){
//            where.append(" and rLevel ='2'"); //rLevel  0:平台级别,1:物业公司级别,2:小区级别,3:锁厂,4：锁厂客户,5:区域经理,6:主板厂商
        }else if("area".equals(type)){
//            where.append(" and rLevel ='5'");
        }

        return sysoptDao.selectList(type,agtCode,communityId);
    }

}
